const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")
const WEAPONS = require("./weapons.js");

const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 253.94,   // 209.13  239   268.88   298.75
        fixdefence: 19.675, // 16.2   18.52  20.83  23.15
        fixedAtt: 16.535,   //  13.62   15.56   17.51  19.45
        reaction : 19.815,  // 16.32   18.65  20.98  23.31
        attRate: 4.955,  // 4.08  4.66  5.25  5.83
        hpRate: 4.955,   // 4.08  4.66  5.25  5.83
        criticalRate: 3.305,   //  2.72  3.11   3.5   3.89
        criticalStrike: 6.605,  //  5.44  6.22  6.99  7.77
        defRate: 6.195,   //  5.1  5.83  6.56   7.29
        charging: 5.505  //  4.53   5.18   5.83   6.48
    }
}

const CLIPDATA = CLIPDATA_TYPE.mid

const CONFIG = {
    chance: 4,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        fixedHp: 4780,
        fixedAtt:311,
        hpRate: 46.6 * 2,
        // dmgRate: 46.6,
        criticalStrike: 62.2,
    },
    clips_initial: [ 
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["hpRate", "charging", "criticalRate", "criticalStrike"],
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["reaction", "charging", "hpRate", "criticalRate"]
    ],
    reactionK : 1.5,
    reactionDmgAdd: 0,
    buffs: [  
        { a1Dmg: 15, azDmg:15, criticalRate: 12*3},  // 新暴击套
        { jk:40} , // 万叶
        { hpRate: 25 } , // 双水
        { dmgRate: 124 } , // 水神
        { jk: 20 }, // 钟离
    ]
}

let charaters = {
    units : {
        name: "那维莱特", 
        reaction: 0,
        dmgZhi: 0,
        charging: 100,
        defRate: 0,
        defence: 576,
        weapontype: "magic", // sword sword2 qiang magic bow
        hp:14695,
        base: 208.32,    
        criticalRate: 5,    
        criticalStrike: 50 + 38.4,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

let tmp = {}
CONFIG.clips_initial.forEach(item => {
    item.forEach(item2 => {
        if(tmp[item2]) {
            tmp[item2] += 1
        } else {
            tmp[item2] = 1
        }
    })
})

/*
    skill: {
        az: {   // 3s
            hpGet: 16, // sd
            hpReduce: "8/0.5s",
            rate: 14.47  // 17.53
        },
        e: {
            rate: 23.16,
            cd: 12,
            sd: 3
        },
        q: {
            rate: 40.06 + 16.39 * 2,  // 47.3 19.35
            sd: 6,
            cd: 18,
            pow: 70
        }
    },
    talent: {
        1: "1.6 azRate",
        2: 30,// dmgRate
    },
    cons: {
        0:                                                1618707
        1: "t 1",                                         1936133   19.6%
        2: "az crslike42",                                2126684   31.38%
        3: "a+3",                                         2525089   56%
        4: "前台被治疗生1sd 4scd",                         3285877 (多喷一波水 同时也会增加多喷一波水得耗时)
        5: "q+3",                                         3319151
        6: "每个水滴延长az1s az每2s发射两道10%倍率攻击"        4486807  (需要水滴捡得很完美 水滴捡得好可以一直喷 不需要一直蓄力浪费时间了)
    }
*/

let cid = "units"
let count_kit = 0;
let combination = getCombination(Array(5*CONFIG.chance + 1).fill().map((_,i)=>i), CONFIG.chance, Object.entries(tmp))
let clips_initial_data = calc_clips_initial()
let fs = require("fs");

let conns = 1 // ming zuo
let selectIndex = 3;
// 40  生水爆 2396215  生水生 2399300  生生爆 2367298  生生生 2358314
// 124 生水爆 3063116  生水生 3067007  生生爆 3146509  生生生 3134469
calc(combination);
function calc(clipSecondData) {
    let charactersDmg = [];
    clipSecondData = clipSecondData.map(clipSecondDataItem => {
        let clipSecond = {}
        clipSecond.des = clipSecondDataItem;
        clipSecond.data = {} 
        for (let secondKey in clipSecond.des) {
            let count =  clipSecond.des[secondKey]
            clipSecond.data[secondKey] = count * CLIPDATA[secondKey]
        }
        return clipSecond
    })
    
    Object.values(WEAPONS).forEach(weapon => {
        if(charaters[cid].weapontype && weapon.weapontype != charaters[cid].weapontype && weapon.weapontype!="all") {return}
        charactersDmg.push(getDMG([charaters[cid],weapon,clips_initial_data,{...CONFIG.clips_main}], clipSecondData, (data,second) => {
            count_kit++;
            data = objValueAdd([data, ...CONFIG.buffs]);
            
            let azCrslike = 0;
            if(conns >= 2) {
                azCrslike = 42
            }
            data.dmgRate += 30
            if(weapon.skill) { weapon.skill(data); }
            data.hp = data.hp*(1 + (data.hpRate||0)/100) + data.fixedHp;
            let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }
            
            let azRate = [0.1447];
            if(conns >= 3) {
                azRate = [0.1753];
            }
            let azrate = 1.3
            if(conns >= 1) {
                azrate = 1.6
            }
            let AZDmg = getDmg({ data:{
                ...data, 
                criticalStrike: data.criticalStrike + azCrslike,
                dmgRate:data.dmgRate + (data.azDmg||0), 
                dmgZhi: data.hp*azRate[0]*azrate}, rate:0
            }).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //

            let AZLiumingDmg = getDmg({ data:{
                ...data, 
                criticalStrike: data.criticalStrike + azCrslike,
                dmgRate:data.dmgRate + (data.azDmg||0), 
                dmgZhi: data.hp*0.2}, rate:0
            }).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            
            let eRate = 0.2316;
            let EDmg = getDmg({ data:{...data, dmgZhi: data.hp*eRate}, rate:0}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            
            let qRate = [0.4006, 0.1639];
            if(conns >=5) {
                qRate = [0.473, 0.1935]; //47.3 19.35
            }
            let Q1Dmg = getDmg({ data:{...data, dmgRate:data.dmgRate+(data.qdmgRate||0),dmgZhi: data.hp*qRate[0]}, rate:0}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            let Q2Dmg = getDmg({ data:{...data, dmgRate:data.dmgRate+(data.qdmgRate||0),dmgZhi: data.hp*qRate[1]}, rate:0}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            
          
            let point = EDmg * 1 + Q1Dmg*1 + Q2Dmg*2 + AZDmg * 8 * 3;   // 
            if(conns >= 4) {
                point +=(AZDmg * 4)
            }
            if(conns >= 6) {
                point +=( AZLiumingDmg * 6 + AZDmg * 4)
            }
            return {point, data, second, dmg:{AZDmg, EDmg, Q1Dmg, Q2Dmg}}
        }))
    })
    
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });

    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[selectIndex];
    console.log(choose);
    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_6命无拐饰金之梦毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }
    fs.writeFileSync("./ret.js", "let a = " + JSON.stringify(choose))
    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count_kit);
}

function getDMG(dataarr, clipSecond, getRet){
    clipSecond = clipSecond.map(second => {
        let panel = objValueAdd([...dataarr, second.data]);
        return  getRet(panel, second)
    })
    clipSecond.sort((b,a)=> a.point-b.point)
    return clipSecond[0]
}

function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
function getCombination (arr, chance, entrys) {
    let num = 5
    var r = [];
    (function f(t, a, n) {
        if (n === 0) {
            if(t.reduce((a1,b1) => a1+b1) !== chance * 5){return}
            let ret = {}
            for (let i in t) {
                if(t[i] > entrys[i][1]*chance){return}
                ret[entrys[i][0]] = t[i]
            }
            r.push(ret)
            return ;
        }
        for (var i = 0, l = a.length; i < l; i++) {
            f(t.concat(a[i]), a, n - 1);
        }
    })([], arr, num);
    return r;
}